﻿using System;
using System.Linq;
using Microsoft.SharePoint;

namespace TSB.SPEventReceiverManager.Entities
{
    public class EventReceiverRepository
    {
        public EventReceiverList GetEventReceivers(Guid listId)
        {
            var list = new EventReceiverList();

            var spList = SPContext.Current.Web.Lists[listId];
            if (spList == null)
            {
                return list;
            }

            list.ListUrl = spList.ParentWebUrl;
            list.ListTitle = spList.Title;

            if (spList.EventReceivers == null || spList.EventReceivers.Count == 0)
            {
                return list;
            }

            var eventReceivers = (from SPEventReceiverDefinition eventReceiver in spList.EventReceivers
                                  select new EventReceiver
                                  {
                                      Name = eventReceiver.Name,
                                      Assembly = eventReceiver.Assembly,
                                      Class = eventReceiver.Class,
                                      Type = eventReceiver.Type.ToString(),
                                      ReceiverId = eventReceiver.Id
                                  }).ToList();

            list.EventReceivers.AddRange(eventReceivers.OrderBy(x => x.Name).ToList());

            return list;
        }

        public Responses AddEventReceiver(Guid listId, string receiverName, int sequenceNumber, SPEventReceiverType eventReceiverType, string assembly, string className)
        {
            var spList = SPContext.Current.Web.Lists[listId];

            if (spList == null || string.IsNullOrEmpty(className) || string.IsNullOrEmpty(assembly))
            {
                return Responses.ListNotExist;
            }

            var eventReceiver = spList.EventReceivers.Add();
            eventReceiver.Name = receiverName;
            eventReceiver.Synchronization = SPEventReceiverSynchronization.Default;
            eventReceiver.Type = eventReceiverType;
            eventReceiver.SequenceNumber = sequenceNumber;
            eventReceiver.Assembly = assembly;
            eventReceiver.Class = className;

            try
            {
                eventReceiver.Update();
            }
            catch(InvalidOperationException ioe)
            {
                if (ioe.Message.Contains("Could not load file or assembly"))
                {
                    return Responses.AddFailedMissingAssembly;
                }
                if (ioe.Message.Contains("Could not load type"))
                {
                    return Responses.AddFailedMissingClass;
                }
            }
            catch 
            {
                return Responses.AddFailed;
            }

            return Responses.AddSuccess;
        }
        
        public Responses DeleteEventReceiver(Guid listId, Guid eventReceiverId)
        {
            var spList = SPContext.Current.Web.Lists[listId];

            if (spList == null)
            {
                return Responses.ListNotExist;
            }

            if (spList.EventReceivers.EventReceiverDefinitionExist(eventReceiverId))
            {
                spList.ParentWeb.AllowUnsafeUpdates = true;
                spList.EventReceivers[eventReceiverId].Delete();
                spList.ParentWeb.AllowUnsafeUpdates = false;
            }
            else
            {
                return Responses.EventReceiverDoesNotExist;
            }

            return Responses.Success;
        }

        public enum Responses
        {
            ListNotExist, EventReceiverDoesNotExist, EventReceiverExists, Success, AddSuccess, AddFailed, AddFailedMissingAssembly, AddFailedMissingClass, AddFailedNoErrors
        }
    }
}
